package com.bfb;

import java.util.ArrayList;

import android.app.TabActivity;
import android.content.Intent;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TabHost;
import android.widget.TextView;
import android.widget.Toast;

import com.bfb.adapters.ImageAdapter;
import com.bfb.helpers.ServerUtilities;
import com.customComponents.PromptDialog;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;

/**
 * This class is responsible for creating the tabs of the game. For each tab an
 * activity is created by creating and instance of the class
 * {@link IngredientsActivity} with new images.
 * 
 * @author Hadeer Diwan
 * 
 */
public class GameActivity extends TabActivity {

	String dishTypeName;
	String dishTypeKey;
	public static String initialIngredients;
	public static ArrayList<String> selectedIngredientNamesList;
	private static final Facebook facebook = Main.facebook;
	String msg = "";
	public static TypedArray harmfulIngredients;
	static String[] deserts;
	public static String[] ingredientTypes;

	public static TextView selectedIngredientsTextView;

	public boolean customize;

	/**
	 * Responsible for assigning images from TypedArrays of images in the
	 * String.xml file to each of the tabs. It also assigns the names of the
	 * tabs to the activities created.
	 */

	@Override
	public void onCreate(Bundle savedInstanceState) {
		harmfulIngredients = getResources().obtainTypedArray(
				R.array.HarmfulIngredientTypeNames);

		super.onCreate(savedInstanceState);
		setContentView(R.layout.game_layout);

		TypedArray dairyDrawables = getResources().obtainTypedArray(
				R.array.DairyDrawables);
		TypedArray dessertDrawables = getResources().obtainTypedArray(
				R.array.DessertDrawables);
		TypedArray fruitDrawables = getResources().obtainTypedArray(
				R.array.FruitDrawables);
		TypedArray meatDrawables = getResources().obtainTypedArray(
				R.array.MeatDrawables);
		TypedArray pastaDrawables = getResources().obtainTypedArray(
				R.array.PastaRiceDrawables);
		TypedArray pastryDrawables = getResources().obtainTypedArray(
				R.array.PastryDrawables);
		TypedArray poultryDrawables = getResources().obtainTypedArray(
				R.array.PoultryDrawables);
		TypedArray seafoodDrawables = getResources().obtainTypedArray(
				R.array.SeafoodDrawables);
		TypedArray spicesDrawables = getResources().obtainTypedArray(
				R.array.SpicesDrawables);
		TypedArray vegetableDrawables = getResources().obtainTypedArray(
				R.array.VegetableDrawables);

		ingredientTypes = getResources().getStringArray(
				R.array.IngredientTypeNames);
		deserts = getResources().getStringArray(R.array.DessertNames);
		tabs(ingredientTypes[0], dairyDrawables,
				getResources().getStringArray(R.array.DairyNames));
		tabs(ingredientTypes[1], dessertDrawables, getResources()
				.getStringArray(R.array.DessertNames));
		tabs(ingredientTypes[2], fruitDrawables,
				getResources().getStringArray(R.array.FruitNames));
		tabs(ingredientTypes[3], meatDrawables,
				getResources().getStringArray(R.array.MeatNames));
		tabs(ingredientTypes[4], pastaDrawables,
				getResources().getStringArray(R.array.PastaRiceNames));
		tabs(ingredientTypes[5], pastryDrawables, getResources()
				.getStringArray(R.array.PastryNames));
		tabs(ingredientTypes[6], poultryDrawables, getResources()
				.getStringArray(R.array.PoultryNames));
		tabs(ingredientTypes[7], seafoodDrawables, getResources()
				.getStringArray(R.array.SeafoodNames));
		tabs(ingredientTypes[8], spicesDrawables, getResources()
				.getStringArray(R.array.SpicesNames));
		tabs(ingredientTypes[9], vegetableDrawables, getResources()
				.getStringArray(R.array.VegetableNames));

		selectedIngredientNamesList = new ArrayList<String>();

		dishTypeName = getIntent().getStringExtra("dishTypeName");
		dishTypeKey = getIntent().getStringExtra("dishTypeKey");
		customize = getIntent().getBooleanExtra("customize", false);

		/**
		 * Setting the initial ingredients to start the game with in case the
		 * user is customizing an already existing dish and not creating a dish
		 * from scratch.
		 * 
		 * @author Rawan Khalil (rawan.tkhalil@gmail.com)
		 */
		initialIngredients = getIntent().getStringExtra("ingredients");
		if (!initialIngredients.equals("")) {
			addInitIngredients();
		}

		/**
		 * Initialize the text view that displays the selected ingredients on
		 * the plate.
		 * 
		 * @author Rawan Khalil (rawan.tkhalil@gmail.com)
		 */
		selectedIngredientsTextView = (TextView) findViewById(R.id.selected_ingredients_textview);
		if (selectedIngredientNamesList.size() != 0) {
			String text = selectedIngredientNamesList.toString();
			selectedIngredientsTextView.setText(text.substring(1,
					text.length() - 1));
		}
	}

	/**
	 * Adds the initial ingredients to the list of already selected ingredients
	 * in case the user is customizing an existing dish.
	 * 
	 * @author Rawan Khalil (rawan.tkhalil@gmail.com)
	 */
	private void addInitIngredients() {
		String[] ingredients = initialIngredients.split(", ");
		for (int i = 0; i < ingredients.length; i++) {
			selectedIngredientNamesList.add(ingredients[i]);
		}
	}

	/**
	 * 
	 * @param s
	 *            string representing the tab name
	 * @param ar
	 *            typed arrays of images IDs
	 * @param ingredient_names
	 *            array of strings containing the names of the ingredients to be
	 *            assigned to the images
	 * 
	 *            This method is responsible for creating a new instance of the
	 *            {@link IngredientsActivity} It added to the intent the images
	 *            to be added to the gallery and their names, in addition to the
	 *            tab name
	 * 
	 * @author Hadeer Diwan (hadeer.diwan@gmail.com)
	 */
	public void tabs(String s, TypedArray ar, String[] ingredient_names) {
		TabHost tabHost = getTabHost();
		TabHost.TabSpec spec;
		Intent intent;

		int[] ingredient_drawables = imagesIDsArray(ar);

		intent = new Intent().setClass(this, IngredientsActivity.class);
		intent.putExtra("ingredient_drawables", ingredient_drawables);
		intent.putExtra("ingredient_names", ingredient_names);
		intent.putExtra("tabName", s);

		spec = tabHost.newTabSpec(s).setIndicator(" " + s + "  ")
				.setContent(intent);
		tabHost.addTab(spec);
	}

	/**
	 * 
	 * @param ar
	 *            typedArray
	 * @return array of integer that contain the IDs
	 * 
	 *         this method loops on the typedArray and copy each element in the
	 *         array of int and return it.
	 * @author Hadeer Diwan (hadeer.diwan@gmail.com)
	 */
	public int[] imagesIDsArray(TypedArray ar) {
		int len = ar.length();
		int[] mImageIds = new int[len];
		for (int i = 0; i < len; i++)
			mImageIds[i] = ar.getResourceId(i, 0);
		ar.recycle();
		return mImageIds;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.game_menu, menu);
		return true;
	}

	/**
	 * Displays the confirmation {@link PromptDialog} for clearing the plate of
	 * all ingredients.
	 * 
	 * @author Rawan Khalil(rawan.tkhalil@gmail.com)
	 * 
	 */
	public void clearConfirmationDialog() {
		PromptDialog dlg = new PromptDialog(GameActivity.this,
				R.string.clear_confirm_title, R.string.clear_confirm_message,
				true, R.string.yes, R.string.cancel) {
			@Override
			public boolean onOkClicked() {
				clear();
				return true;
			}
		};
		dlg.show();
	}

	/**
	 * Resets the list of ingredients and the text view to clear them of all
	 * ingredients and reset the game.
	 * 
	 * @author Rawan Khalil(rawan.tkhalil@gmail.com)
	 * 
	 */
	public void clear() {
		selectedIngredientNamesList = new ArrayList<String>();
		selectedIngredientsTextView.setText("");
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int itemId = item.getItemId();

		if (itemId == R.id.share_facebook) {
			if (!Networking.isNetworkAvailable(getBaseContext())) {
				PromptDialog dlg = new PromptDialog(GameActivity.this,
						R.string.internetConnectionPromptTitle,
						R.string.internetConnectionPromptMsgFB, false, -1,
						R.string.ok) {
					@Override
					public boolean onOkClicked() {
						return true;
					}
				};
				dlg.show();

			} else {
				if (selectedIngredientNamesList.size() == 0) {
					PromptDialog dlg = new PromptDialog(GameActivity.this,
							R.string.noIngedientsSelectedTitle,
							R.string.noIngedientsSelectedMsg, false, -1,
							R.string.ok) {
						@Override
						public boolean onOkClicked() {
							return true;
						}
					};
					dlg.show();
				} else {
					postOnWallAuthorize();
				}
			}
		} else {
			/**
			 * The handler of clicking either on "Find Matching Dishes" or
			 * "Clear" menu items. Calling the corresponding method for each
			 * action.
			 * 
			 * @author Rawan Khalil (rawan.tkhalil@gmail.com)
			 */
			if (itemId == R.id.match_dish_menuitem) {
				matchDish();
			} else {
				if (itemId == R.id.clear_menuitem) {
					clearConfirmationDialog();
				}
			}
		}

		return super.onOptionsItemSelected(item);
	}

	public void postOnWallAuthorize() {
		if (!facebook.isSessionValid())
			facebook.authorize(this, new String[] { "publish_stream" },
					new DialogListener() {
						@Override
						public void onComplete(Bundle values) {
							Main.user.setAllowFB(true);
							postOnWallHelper();
						}

						@Override
						public void onFacebookError(FacebookError error) {
							Toast.makeText(getBaseContext(),
									getString(R.string.fbError),
									Toast.LENGTH_LONG).show();
						}

						@Override
						public void onError(DialogError e) {
							Toast.makeText(getBaseContext(),
									getString(R.string.fbError),
									Toast.LENGTH_LONG).show();
						}

						@Override
						public void onCancel() {
						}
					});
		else
			postOnWallHelper();

	}

	public void postOnWallHelper() {
		try {
			msg = getString(R.string.iCreatedADish)
					+ selectedIngredientNamesList.toString();
			Log.e("Ingredients", msg);
			postOnWall();
		} catch (Exception e) {
			Log.e("Exception", e.getMessage());
		}

	}

	public void postOnWall() {
		Log.d("Tests", "Testing graph API wall post");
		ServerUtilities.background(new Runnable() {
			@Override
			public void run() {

				try {
					// Toast.makeText(getBaseContext(),
					// msg,Toast.LENGTH_LONG).show();
					String response = facebook.request("me");
					Bundle parameters = new Bundle();
					parameters.putString("message", msg);
					parameters.putString("description", "test test test");
					response = facebook.request("me/feed", parameters, "POST");
					Log.d("Tests", "got response: " + response);
					if (response == null || response.equals("")
							|| response.equals("false")) {
						Log.v("Error", "Blank response");
					}
				} catch (Exception e) {
					runOnUiThread(new Runnable() {

						@Override
						public void run() {
							Toast.makeText(getBaseContext(),
									getString(R.string.fbError),
									Toast.LENGTH_LONG).show();
						}
					});
				}
			}
		});

	}

	public void matchDish() {
		if (ImageAdapter.toastOn == true)
			ImageAdapter.toast.cancel();
		if (!Networking.isNetworkAvailable(getBaseContext())) {
			PromptDialog dlg = new PromptDialog(GameActivity.this,
					R.string.internetConnectionPromptTitle,
					R.string.internetConnectionPromptMsg, false, -1,
					R.string.ok) {
				@Override
				public boolean onOkClicked() {
					return true;
				}
			};
			dlg.show();

		} else {
			/**
			 * Calls the {@link MatchDishes} activity by creating a new intent
			 * and passing it all the ingredients the user has selected and the
			 * dish type name and key.
			 * 
			 * @author Rawan Khalil (rawan.tkhalil@gmail.com)
			 */
			Intent matchDishIntent = new Intent(this, MatchDishes.class);
			Bundle b = new Bundle();
			b.putString("dishTypeName", dishTypeName);
			b.putString("dishTypeKey", dishTypeKey);
			String ingredientNames = prepareIngredientString();
			b.putString("ingredientNames", ingredientNames);
			matchDishIntent.putExtras(b);
			startActivity(matchDishIntent);

		}
	}

	/**
	 * Prepares the list of ingredients and converts it into a string to be
	 * passed to the {@link MatchDishes} activity for matching.
	 * 
	 * @return String
	 * 
	 * @author Rawan Khalil (rawan.tkhalil@gmail.com)
	 */
	private String prepareIngredientString() {
		String result = "";
		for (String ingredient : selectedIngredientNamesList) {
			result += ingredient.replaceAll(" ", "_") + " ";
		}
		return result;
	}

}